
import React, { useEffect, useRef } from "react";
import { OrbitControls } from "@three-ts/orbit-controls";
import * as THREE from "three";
type Props = {};

const Nbbjt = (props: Props) => {
    const myref = useRef<any>(null);
    const _thre: any = THREE;
    useEffect(() => {
      let innerWidth = window.innerWidth;
      let innerHeight = window.innerHeight;
      // 场景
      let scene = new _thre.Scene();
      scene.background = new _thre.Color(0x160016);
      // 透视相机
      let camera = new _thre.PerspectiveCamera(
        60,
        innerWidth / innerHeight,
        1,
        1000
      );
      camera.position.set(0, 4, 21);
      // WebGL渲染器常量
      let renderer = new _thre.WebGLRenderer();
      renderer.setSize(innerWidth, innerHeight);
      //添加到页面中
      myref.current.appendChild(renderer.domElement);
      //大小
      window.addEventListener("resize", (event) => {
        camera.aspect = innerWidth / innerHeight;
        camera.updateProjectionMatrix();
        renderer.setSize(innerWidth, innerHeight);
      });
      // 轨道控制器
      const controls = new OrbitControls(camera, renderer.domElement);
      controls.enableDamping = true;
      controls.enablePan = false;
  
      let gu = {
        time: { value: 0 },
      };
  
      let sizes: any[] = [];
      let shift: any[] = [];
      let pushShift = () => {
        shift.push(
          Math.random() * Math.PI,
          Math.random() * Math.PI * 2,
          (Math.random() * 0.9 + 0.1) * Math.PI * 0.1,
          Math.random() * 0.9 + 0.1
        );
      };
      //内圈的数量
      let pts = new Array(50000).fill(sizes).map((p) => {
        sizes.push(Math.random() * 1.5 + 0.5);
        pushShift();
        return new _thre.Vector3()
          .randomDirection()
          .multiplyScalar(Math.random() * 0.5 + 9.5);
      });
      //外圈的数量
      for (let i = 0; i < 100000; i++) {
        let r = 10,
          R = 40;
        let rand = Math.pow(Math.random(), 1.5);
        let radius = Math.sqrt(R * R * rand + (1 - rand) * r * r);
        pts.push(
          new _thre.Vector3().setFromCylindricalCoords(
            radius,
            Math.random() * 2 * Math.PI,
            (Math.random() - 0.5) * 2
          )
        );
        sizes.push(Math.random() * 1.5 + 0.5);
        pushShift();
      }
  
      let g = new _thre.BufferGeometry().setFromPoints(pts);
      g.setAttribute("sizes", new _thre.Float32BufferAttribute(sizes, 1));
      g.setAttribute("shift", new _thre.Float32BufferAttribute(shift, 4));
      let m = new _thre.PointsMaterial({
        size: 0.125,
        transparent: true,
        depthTest: false,
        blending: _thre.AdditiveBlending,
        onBeforeCompile: (shader: {
          uniforms: { time: { value: number } };
          vertexShader: string;
          fragmentShader: string;
        }) => {
          shader.uniforms.time = gu.time;
          shader.vertexShader = `
                    uniform float time;
                    attribute float sizes;
                    attribute vec4 shift;
                    varying vec3 vColor;
                    ${shader.vertexShader}
                  `
            .replace(`gl_PointSize = size;`, `gl_PointSize = size * sizes;`)
            .replace(
              `#include <color_vertex>`,
              `#include <color_vertex>
                      float d = length(abs(position) / vec3(40., 10., 40));
                      d = clamp(d, 0., 1.);
                      vColor = mix(vec3(227., 155., 0.), vec3(100., 50., 255.), d) / 255.;
                    `
            )
            .replace(
              `#include <begin_vertex>`,
              `#include <begin_vertex>
                      float t = time;
                      float moveT = mod(shift.x + shift.z * t, PI2);
                      float moveS = mod(shift.y + shift.z * t, PI2);
                      transformed += vec3(cos(moveS) * sin(moveT), cos(moveT), sin(moveS) * sin(moveT)) * shift.w;
                    `
            );
          //console.log(shader.vertexShader);
          shader.fragmentShader = `
                    varying vec3 vColor;
                    ${shader.fragmentShader}
                  `
            .replace(
              `#include <clipping_planes_fragment>`,
              `#include <clipping_planes_fragment>
                      float d = length(gl_PointCoord.xy - 0.5);
                      //if (d > 0.5) discard;
                    `
            )
            .replace(
              `vec4 diffuseColor = vec4( diffuse, opacity );`,
              `vec4 diffuseColor = vec4( vColor, smoothstep(0.5, 0.1, d)/* * 0.5 + 0.5*/ );`
            );
          //console.log(shader.fragmentShader);
        },
      });
      let p = new _thre.Points(g, m);
      p.rotation.order = "ZYX";
      p.rotation.z = 0.2;
      scene.add(p);
  
      let clock = new _thre.Clock();
  
      renderer.setAnimationLoop(() => {
        controls.update();
        let t = clock.getElapsedTime() * 0.5;
        gu.time.value = t * Math.PI;
        p.rotation.y = t * 0.05;
        renderer.render(scene, camera);
      });
    }, []);
  return  <div className="myThree" ref={myref}></div>;
};

export default Nbbjt;
